﻿using Admin.NET.Application.Entity;
using Admin.NET.Application.Service.ProjectDailys.Dto;
using Admin.NET.Application.Service.Projects.Dto;
using Admin.NET.Application.Service.ProjectWorkers;
using Admin.NET.Core;
using Furion.DependencyInjection;
using Furion.FriendlyException;
using Nest;
using NewLife;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Admin.NET.Application.Service.Projects;
public class ProjectService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<Project> _project;
    private readonly SqlSugarRepository<ProjectBindOrg> _ProjectBindOrg;
    private readonly SqlSugarRepository<SysOrg> _SysOrg;
    private readonly SqlSugarRepository<ProjectDaily_Child> _ProjectDailyChild;

    private readonly ProjectWorkerService _projectWorkerService;
    private readonly UserManager _userManager;
    private readonly SqlSugarRepository<ProjectWorker> _ProjectWorker;
    private readonly SqlSugarRepository<SysDictData> _SysDictData;
    private readonly SqlSugarRepository<SysUser> _SysUser;
    private readonly SqlSugarRepository<ProjectDaily> _ProjectDaily;


    public ProjectService(SqlSugarRepository<Project> project,
                          SqlSugarRepository<ProjectWorker> ProjectWorker,
                           SqlSugarRepository<ProjectBindOrg> ProjectBindOrg,
                          UserManager userManager,
                           SqlSugarRepository<ProjectDaily_Child> ProjectDailyChild,
                           SqlSugarRepository<SysOrg> SysOrg,
    SqlSugarRepository<SysDictData> sysDictData,
                          ProjectWorkerService projectWorkerService, SqlSugarRepository<SysUser> SysUser, SqlSugarRepository<ProjectDaily> ProjectDaily)
    {
        _project = project;
        _ProjectBindOrg = ProjectBindOrg;
        _ProjectWorker = ProjectWorker;
        _SysOrg = SysOrg;
        _ProjectDailyChild = ProjectDailyChild;
        _userManager = userManager;
        _SysDictData = sysDictData;
        _projectWorkerService = projectWorkerService;
        _ProjectDaily = ProjectDaily;
        _SysUser = SysUser;
    }
    [DisplayName("新增/更新项目")]
    [ApiDescriptionSettings(Name = "AddOrUpdateProject"), HttpPost]
    public async Task<bool> AddOrUpdateProject(ProjectAddInput Input)
    {
        if (Input == null)
        {
            throw Oops.Oh("请输入数据");
        }

        if (!Input.Id.Equals(0))
        {
            Project project = await _project.AsQueryable().FirstAsync(p => p.Id.Equals(Input.Id));
            project = Input.Adapt<Project>();
            await _project.UpdateAsync(project);
            if (!Input.department.IsNullOrEmpty()) {
                await BindProjectOrg(project.Id, long.Parse(Input.department));

            }
            await _projectWorkerService.BindProjectWorkers(Input.ProjectMember, project.Id);
        }
        else
        {
            Project project = Input.Adapt<Project>();
            await _project.InsertAsync(project);
            if (!Input.department.IsNullOrEmpty())
            {
                await BindProjectOrg(project.Id, long.Parse(Input.department));
            }
            await _projectWorkerService.BindProjectWorkers(Input.ProjectMember, project.Id);
        }
        return true;
    }

    [DisplayName("查询项目列表")]
    [ApiDescriptionSettings(Name = "GetProjects"), HttpPost]
    public async Task<SqlSugarPagedList<PageProjectOutput>> GetProjectsList(PageProjectInput Input)
    {
        if (Input == null)
        {
            throw Oops.Oh("请输入数据");
        }
        var projectsList = await _project.AsQueryable()
                .WhereIF(!Input.Name.IsNullOrEmpty(), p => p.Name.Contains(Input.Name))
                .Select(p=>new PageProjectOutput
                {
                    id = p.Id,
                    Name = p.Name,
                    IsFinsih = p.IsFinsih,
                })
                .ToPagedListAsync(Input.Page,Input.PageSize);
        foreach(var project in projectsList.Items )
        {
            project.orgName = "";
            var bindorg = _ProjectBindOrg.AsQueryable().Where(p=>p.ProjectId.Equals(project.id)).ToList();
            foreach(var item in bindorg)
            {
                var org = await _SysOrg.AsQueryable().FirstAsync(p => p.Id.Equals(item.OrgId));
                if(org != null)
                {
                    project.orgName += org.Name+",";
                }
            }
            if (project.orgName.Length > 0)
            {
                project.orgName = project.orgName.TrimEnd(",");
            }
            project.productTime =await GetTime(project.id, "产品", Input.dataRange);
            project.projectTime = await GetTime(project.id, "项目", Input.dataRange);
            project.frontTime = await GetTime(project.id, "前端", Input.dataRange);
            project.backendTime = await GetTime(project.id, "后端", Input.dataRange);
            project.totalTime = project.productTime+ project.projectTime+project.frontTime+project.backendTime;
            project.cost = (int)(Math.Floor((project.productTime+project.projectTime+project.frontTime+project.backendTime)*1000)/7);
        }
        return projectsList;
    }

    /// <summary>
    /// 获取对应的组织的用时
    /// 逻辑先找全部的人。然后再在通过项目筛选
    /// </summary>
    /// <param name="projectId"></param>
    /// <returns></returns>
    public async Task<Decimal> GetTime(long projectId,string name,List<DateTime> dataRange)
    {
        Decimal output = 0;
        //SysDictData data  = await _SysDictData.AsQueryable().FirstAsync(p=>p.Code.Equals(code)&&p.DictTypeId.Equals(14581124590533));
        //List<long> userids = _ProjectWorker.AsQueryable().Where(p=>p.ProjectId.Equals(projectId)&&p.RoleId.Equals(data.Id)).Select(p=>p.UserId).ToList();
        //if (userids.Count == 0) {
        //    return 0;
        //}
        List<long> orgs = await _SysOrg.AsQueryable().Where(p => p.Name.Equals(name)).Select(p=>p.Id).ToListAsync();
        //List<ProjectDaily> ProjectDailys = _ProjectDaily.AsQueryable().Where(p => userids.Contains((long)p.CreateUserId) && p.ProjectId.Equals(projectId)).ToList();
        if (!dataRange.IsNullOrEmpty())
        { 
            List<ProjectDaily_Child> projectDailysChilds =await _ProjectDailyChild.AsQueryable()
                .LeftJoin<ProjectDaily>((p, q) => p.ProjectDailyId.Equals(q.Id))
                .WhereIF(!dataRange[0].IsNullOrEmpty(), (p, q) => p.ToWrittenTime >= dataRange[0])
                .WhereIF(!dataRange[1].IsNullOrEmpty(), (p, q) => p.ToWrittenTime <= dataRange[1])
                .Where((p, q) => q.ProjectId.Equals(projectId)&&q.isAbondon.Equals(false))
                .Select((p, q) => p).ToListAsync();
            foreach (ProjectDaily_Child project in projectDailysChilds)
            {
                Boolean isexist = await _SysUser.AsQueryable().AnyAsync(p => p.Id.Equals(project.CreateUserId) && orgs.Contains(p.OrgId));
                if (isexist)
                {

                    output = (decimal)(output + project.WorkUse);
                }
            }
            return output;
        }
        else
        {
            List<ProjectDaily> ProjectDailys = _ProjectDaily.AsQueryable().Where(p => p.ProjectId.Equals(projectId) && !p.isAbondon.Equals(true)).ToList();
            foreach (ProjectDaily project in ProjectDailys)
            {
                Boolean isexist = await _SysUser.AsQueryable().AnyAsync(p => p.Id.Equals(project.CreateUserId) && orgs.Contains(p.OrgId));
                if (isexist)
                {

                    output = (decimal)(output + project.UseTime);
                }
            }
            return output;
        }
    }

    [DisplayName("查询项目列表")]
    [ApiDescriptionSettings(Name = "OverProject"), HttpGet]
    public async Task OverProject([FromQuery] long id)
    {
        if (id.Equals(0))
        {
            throw Oops.Oh("请输入数据");
        }
        Project project = await _project.AsQueryable().FirstAsync(p => p.Id.Equals(id));
        project.IsFinsih = true;
        await _project.UpdateAsync(project);
    }
    [DisplayName("删除项目")]
    [ApiDescriptionSettings(Name = "DelProject"), HttpGet]
    public async Task<bool> DelProject([FromQuery]long id)
    {
        if (id.Equals(0))
        {
            throw Oops.Oh("请输入数据");
        }
        await _project.DeleteByIdAsync(id);
        var linkorg = _ProjectBindOrg.AsQueryable().Where(p => p.ProjectId.Equals(id)).ToList();
        await _ProjectBindOrg.DeleteAsync(linkorg);
        var projectworker = _ProjectWorker.AsQueryable().Where(p => p.ProjectId.Equals(id)).ToList();
        await _ProjectWorker.DeleteAsync(projectworker);
        return true;
    }

    [DisplayName("获取属于自己的项目")]
    [ApiDescriptionSettings(Name = "GetOwnProjects"), HttpGet]
    public async Task<List<OwnProjectOutput>> GetOwnProjects([FromQuery]Project Input)
    {
        
        //List<long> projectIds =  await _ProjectWorker.AsQueryable().Where(p=>p.UserId.Equals(_userManager.UserId)).Select(p=>p.ProjectId).ToListAsync();
        List<OwnProjectOutput> projects = await _project.AsQueryable()
            //.Where(p => projectIds.Contains(p.Id))
            .WhereIF(!Input.Name.IsNullOrEmpty(),p=>p.Name.Contains(Input.Name)).Select(p => new OwnProjectOutput { Id= p.Id,Name=p.Name }).ToListAsync();
        return projects;
    }

    public async Task<Boolean> BindProjectOrg(long projectId,long department)
    {
        //先删除后新增
        var linkorg = _ProjectBindOrg.AsQueryable().Where(p => p.ProjectId.Equals(projectId)).ToList();
        await _ProjectBindOrg.DeleteAsync(linkorg);
        List<ProjectBindOrg> temp = new List<ProjectBindOrg>();
        //foreach(long item in department)
        //{
            temp.Add(new ProjectBindOrg
            {
                ProjectId = projectId,
                OrgId = department
            });
        //}
        await _ProjectBindOrg.InsertRangeAsync(temp);

        return true;
    }

    [DisplayName("获取项目详情")]
    [ApiDescriptionSettings(Name = "GetProjectDetail"), HttpGet]
    public async Task<ProjectDetailOutput> GetProjectDetail([FromQuery]long id)
    {
        ProjectDetailOutput Output = new ProjectDetailOutput();
        Project projectDetail = await _project.GetByIdAsync(id);

        Output = projectDetail.Adapt<ProjectDetailOutput>();
        ProjectBindOrg department = await _ProjectBindOrg.AsQueryable().FirstAsync(p => p.ProjectId.Equals(id));
        if (!department.IsNullOrEmpty())
        {
            if(department.OrgId == 0) {
                Output.department = null;

            }
            else
            {
                Output.department = department.OrgId.ToString();

            }
        }
        List<SysDictData> sysDictDatas = await _SysDictData.AsQueryable().Where(p=>p.DictTypeId.Equals(14581124590533)).ToListAsync();
        List<ProjectMemer> memer = new List<ProjectMemer>();
        Output.ProjectMember = new List<ProjectMemer>();
        foreach(SysDictData temp in sysDictDatas)
        {
            List<long> projectWorkers = await _ProjectWorker.AsQueryable().Where(p=>p.ProjectId.Equals(id)&&p.RoleId.Equals(temp.Id)).Select(p=>p.UserId).ToListAsync();

            memer.Add(new ProjectMemer
            {
                Code= temp.Code,
                id = temp.Id,
                Name = temp.Value,
                userid = projectWorkers
            });
        }
        Output.ProjectMember = memer;

        return Output;
    }

    [DisplayName("显示项目涉及部门")]
    [ApiDescriptionSettings(Name = "GetProjectDepartment"), HttpGet]
    public async Task<List<ProjectMemer>> GetProjectDepartment()
    {     
        List<SysDictData> sysDictDatas = await _SysDictData.AsQueryable().Where(p => p.DictTypeId.Equals(14581124590533)).ToListAsync();
        List<ProjectMemer> memer = new List<ProjectMemer>();
        foreach (SysDictData temp in sysDictDatas)
        {
            memer.Add(new ProjectMemer
            {
                Code = temp.Code,
                id = temp.Id,
                Name = temp.Value,
                userid = new List<long>()
            });
        }
        return memer;
    }
}
